package com.whims.RAM_Distribution;

/**
 * 内存分配测试
 */
public class Distribution {

    private static final int _1MB = 1024 * 1024;

    public static void main(String []args){
//        testObjFirstEden();
//        testBigObjJoinOld();
//        testLongObjJoinOld();
//          testDynamicObjJoinOld();
        testSpaceGuarantee();
    }




    /**
     * 测试对象优先在Eden上分配
     * vm options:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     *
     *  -verbose:gc  监视虚拟机内存回收的情况,
     *  -Xms20M -Xmx20M -Xmn10M   限制Java堆20M大，不可扩展。其中10M分配给新生代，剩下给老年代
     *  -XX:+PrintGCDetails  打印GC日志
     *  -XX:SurvivorRatio=8  新生代区域比例8:1
     */
    public static void testObjFirstEden(){
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        //发生一次Minor GC（Eden空间不足），GC后由于6M的3个对象无法移到Survivor（只有1M）
        allocation4 = new byte[4 * _1MB];
    }


    /**
     * 测试大对象直接进入老年代
     * vm options:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * -XX:PretenureSizeThreshold=3145728 -XX:+UseSerialGC
     *
     *  -verbose:gc  监视虚拟机内存回收的情况,
     *  -Xms20M -Xmx20M -Xmn10M   限制Java堆20M大，不可扩展。其中10M分配给新生代，剩下给老年代
     *  -XX:+PrintGCDetails  打印GC日志
     *  -XX:SurvivorRatio=8  新生代区域比例8:1
     *  -XX:PretenureSizeThreshold=3145728  超过3M的对象都分配到老年代
     *  -XX:+UseSerialGC  指定使用Serial收集器
     */
    public static void testBigObjJoinOld(){
        byte[] allocation  = new byte[4 * _1MB];
    }


    /**
     *
     * 测试动态对象年龄判定
     * vm options:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * -XX:+UseSerialGC -XX:MaxTenuringThreshold=1
     *
     *  -verbose:gc  监视虚拟机内存回收的情况,
     *  -Xms20M -Xmx20M -Xmn10M   限制Java堆20M大，不可扩展。其中10M分配给新生代，剩下给老年代
     *  -XX:+PrintGCDetails  打印GC日志
     *  -XX:SurvivorRatio=8  新生代区域比例8:1
     *  -XX:+UseSerialGC  指定使用Serial收集器
     *  -XX:MaxTenuringThreshold=1 设置晋升到老年代的年龄阈值
     */
    public static void testLongObjJoinOld(){
        byte[] allocation1, allocation2, allocation3 ;
        allocation1 = new byte[ _1MB / 4 ];
        //什么时候进入老年代取决于XX:MaxTenuringThreshold设置(若注释allocation2一行代码，就会发现allocation1不会晋升到老年代)
        allocation2 = new byte[ 4 * _1MB];
        allocation3 = new byte[4 * _1MB];
        allocation3 = null;
        allocation3 = new byte[4 * _1MB];
    }



    /**
     *
     * 测试动态对象年龄判定
     * vm options:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * -XX:+UseSerialGC -XX:MaxTenuringThreshold=15
     *
     *  -verbose:gc  监视虚拟机内存回收的情况,
     *  -Xms20M -Xmx20M -Xmn10M   限制Java堆20M大，不可扩展。其中10M分配给新生代，剩下给老年代
     *  -XX:+PrintGCDetails  打印GC日志
     *  -XX:SurvivorRatio=8  新生代区域比例8:1
     *  -XX:+UseSerialGC  指定使用Serial收集器
     *  -XX:MaxTenuringThreshold=15 设置晋升到老年代的年龄阈值
     */
    public static void testDynamicObjJoinOld(){
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[ _1MB / 4 ];
        //allocation1+ allocation2 大于survivor空间一半
        allocation2 = new byte[  _1MB / 4];
        allocation3 = new byte[4 * _1MB];
        allocation4 = new byte[4 * _1MB];
        allocation4 = null;
        allocation4 = new byte[4 * _1MB];
    }


    /**
     *
     * 测试内存分配担保
     * vm options:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * -XX:-HandlePromotionFailure
     *
     *  -verbose:gc  监视虚拟机内存回收的情况,
     *  -Xms20M -Xmx20M -Xmn10M   限制Java堆20M大，不可扩展。其中10M分配给新生代，剩下给老年代
     *  -XX:+PrintGCDetails  打印GC日志
     *  -XX:SurvivorRatio=8  新生代区域比例8:1
     *  -XX:-HandlePromotionFailure 设置不允许担保
     *  -XX:+HandlePromotionFailure 设置允许担保
     */
    public static void testSpaceGuarantee(){
        byte[] allocation1, allocation2, allocation3, allocation4,
        allocation5, allocation6, allocation7;

        allocation1 = new byte[2 * _1MB  ];
        allocation2 = new byte[2 * _1MB  ];
        allocation3 = new byte[2 * _1MB  ];
        allocation1 = null;

        allocation4 = new byte[2 * _1MB  ];
        allocation5 = new byte[2 * _1MB  ];
        allocation6 = new byte[2 * _1MB  ];
        allocation4 = null;
        allocation5 = null;
        allocation6 = null;

        allocation7 = new byte[2 * _1MB  ];
    }

}
